Programmatially Send files using OBEX Object Push over the Microsoft Bluetooth Stack

A while back during my senior project of my BSc computer science studies, I wrote an implementation of parts_of_HCI, L2CAP, SDP, RFCOMM and OBEX on top of freebt.net’s bluetooth implementation for Windows.

That same OBEX code was modified to be used with the MS BT stack to send files over bluetooth - please see the code of WMouseXP open-source version, the fuction “sendFile” at https://github.com/ykasidit/WMouseXP/blob/master/src/WMouseXPDlg.cpp and the main OBEX layer packet code was https://github.com/ykasidit/WMouseXP/blob/master/src/OBEX.cpp - sorry for the low quality/cleanliness of code here - it was written when I was still just starting C and C++ programming back then - but it worked when tested with many Bluetooth devices/phones.

The main part is making the OBEX object:

bool CWMouseXPDlg::SendFile(char* devaddr, int port, BYTE* dataptr, DWORD datalen)
{
	//close socket to make sure it is closed, new session
	closesocket(iSocket);    
	WSACleanup();

	if(!InitSocket())
	{
		throw "Initialize MS Bluetooth stack/driver failed";		
	}

	SOCKADDR_BTH sa = { 0 };
	int sa_len = sizeof(sa);


	if( SOCKET_ERROR == WSAStringToAddress( devaddr, AF_BTH,
	NULL, (LPSOCKADDR) &sa, &sa_len ) ) 
	{
		throw "Convert BT address WSAStringToAddress failed";	
	}

	sa.port = port;

	if( sa.port == 0 ) {
		iStep1Label.SetWindowText("Invalid device OBEX port specified");
	return false;
	}	




	//open socket



	//Made new send and recv functions implements a timer, see SendViaSocketL and RevcViaSocketL

	//try catch handles when send and recv fails






	//make safe cleanup when exceptions occur



	OBEXPutCommand* opc = NULL;

	OBEXPacket* obexPktToSend = NULL; //file part packet


	bool success = false;

	try{
              
				iStep1Label.SetWindowText("Waiting for phone to accept file...");

				StartBTInteractionTimer(); //so we don't wait too long for a user to respond

				if(SOCKET_ERROR != connect( iSocket, (LPSOCKADDR) &sa, sa_len ))
                  {
						//Send OBEX Connect				

						StopBTInteractionTimer();  	

						m_InstallPic.Draw();

					    OBEXConnectPacket obexConnectPkt(Opcode_Connect,0x4000);				

                        BYTE recvBuff[512];												

						SendViaSocketL((const char*) (obexConnectPkt.wholePacket),obexConnectPkt.packetLength);


						bool startedPut	= false;
						USHORT theirMaxOBEXPacketSize = 0;					


						//See response, then Send all OBEX file packets											

						int nreceived = RecvViaSocketL((char*)recvBuff,512);						



                        if(recvBuff[0] == RspCode_Success)
                        {
                              	
							iStep1Label.SetWindowText("Connect OBEX Success");		


						while(1)
						{

							if(startedPut)
								nreceived = RecvViaSocketL((char*)recvBuff,512);


							OBEXPacket obexRcvdPkt(recvBuff,nreceived);


							if(!startedPut)
							{

									if(obexRcvdPkt.wholePacket->code == RspCode_Success)
									{
										iStep1Label.SetWindowText("OBEX connection successful");

										BEUS tmo(((BYTE*)(obexRcvdPkt.wholePacket->data))+2);					
										theirMaxOBEXPacketSize = tmo.getValUSHORT(); 

										char buf[50] = {0};
										sprintf(buf,"Their max OBEX packet size: %d",theirMaxOBEXPacketSize);
										iStep1Label.SetWindowText(buf);



										//file->Open("card.vcf",CFile::modeRead|CFile::typeBinary);
										//file->Open("img.jpg",CFile::modeRead|CFile::typeBinary);
										//if(opc)
										//	delete opc;

										 opc = new OBEXPutCommand("WMouseXP.jar",theirMaxOBEXPacketSize,dataptr,datalen);							

										//sprintf(buf,"N OBEX puts to send: %d",opc->nPacketsToSend);
										iStep1Label.SetWindowText("Sending File...");
										//devicesLB->DrawAnimatedRects()


													obexPktToSend = opc->CgetNextPacket();

													SendViaSocketL((const char*) (obexPktToSend->wholePacket),obexPktToSend->packetLength);

													delete obexPktToSend;
													obexPktToSend = NULL;

													startedPut = true;

									}


							}						
							else
							{
									if(obexRcvdPkt.wholePacket->code == RspCode_Success)
										{
											//send obex disc
											iStep1Label.SetWindowText("File sent via Bluetooth");
											success = true;

											OBEXPacket dsc(Opcode_Disconnect,NULL,0);

											//AddLog("Sending OBEX Disconnect Request");
										    SendViaSocketL((const char*) (dsc.wholePacket),dsc.packetLength);					
											//AddLog("OBEX Disconnect Sent");					
											iStep1Label.SetWindowText("File sent via Bluetooth");
											break;

										}
										else
									if(obexRcvdPkt.wholePacket->code == RspCode_Continue)
										{
											obexPktToSend = opc->CgetNextPacket();	

											SendViaSocketL((const char*) (obexPktToSend->wholePacket), obexPktToSend->packetLength);

											delete obexPktToSend;
											obexPktToSend = NULL;//avoid double deletion

										}
									else
										{
											throw "Unknown OBEX Response";
											//break; throw already broke...
										}


							}//end else of if(!started)


							}//end while	




						}//end if(recvBuff[0] == RspCode_Success)			
						else
						{
							throw("OBEX handshake failed.");							

						}	
                        

				}// end if(connect!=SOCKET_ERROR)                                          
				else
      			{			StopBTInteractionTimer();
							throw "Connection Declined or Timed-Out";
				}





	}
	catch(char* exception)
	{
		iStep1Label.SetWindowText(exception);
	}


	delete obexPktToSend;
	delete opc;


	closesocket(iSocket);      
	WSACleanup();

	return success;

}


blog comments powered by Disqus

This ClearEvo.com blog is powered by Debian GNU/Linux, running lighttpd, generated using jekyll on Ubuntu.

Subscribe for new updates