static GSM_Error MBUS2_SendAck(GSM_StateMachine *s, unsigned char type, unsigned char sequence) { GSM_Device_Functions *Device = s->Device.Functions; unsigned char buffer[6]= {0}; int i=0,length=0,write_data=0; buffer[0] = MBUS2_FRAME_ID; buffer[1] = MBUS2_DEVICE_PHONE; /* destination */ buffer[2] = MBUS2_DEVICE_PC; /* source */ buffer[3] = MBUS2_ACK_BYTE; buffer[4] = sequence; buffer[5] = '\0'; length=strlen(buffer); /* Calculating checksum */ for (i = 0; i < length; i++) { buffer[5] ^= buffer[i]; } smprintf_level(s, D_TEXT, "[Sending Ack of type %02x, seq: %x]\n",type,sequence); /* Sending to phone */ write_data=Device->WriteDevice(s,buffer,length); if (write_data!=length) { return ERR_DEVICEWRITEERROR; } return ERR_NONE; }
static GSM_Error FBUS2_SendAck(GSM_StateMachine *s, unsigned char MsgType, unsigned char MsgSequence) { unsigned char buffer[2]={0}; buffer[0] = MsgType; buffer[1] = MsgSequence; smprintf_level(s, D_TEXT, "[Sending Ack of type %02x, seq %x]\n", buffer[0], buffer[1]); /* Sending to phone */ return FBUS2_WriteFrame(s, buffer, 2, FBUS2_ACK_BYTE); }
GSM_Error GSM_WaitFor (GSM_StateMachine *s, unsigned const char *buffer, int length, int type, int timeout, GSM_Phone_RequestID request) { GSM_Phone_Data *Phone = &s->Phone.Data; GSM_Error error; int reply; if (s->CurrentConfig->StartInfo) { if (Phone->StartInfoCounter > 0) { Phone->StartInfoCounter--; if (Phone->StartInfoCounter == 0) s->Phone.Functions->ShowStartInfo(s,FALSE); } } Phone->RequestID = request; Phone->DispatchError = ERR_TIMEOUT; for (reply=0;reply<s->ReplyNum;reply++) { if (reply!=0) { smprintf_level(s, D_ERROR, "[Retrying %i type 0x%02X]\n", reply, type); } error = s->Protocol.Functions->WriteMessage(s, buffer, length, type); if (error!=ERR_NONE) return error; /* Special case when no reply is expected */ if (request == ID_None) { return ERR_NONE; } error = GSM_WaitForOnce(s, buffer, length, type, timeout); if (error != ERR_TIMEOUT) return error; } return ERR_TIMEOUT; }
static GSM_Error FBUS2_StateMachine(GSM_StateMachine *s, unsigned char rx_char) { GSM_Protocol_FBUS2Data *d = &s->Protocol.Data.FBUS2; unsigned char frm_num, seq_num; gboolean correct = FALSE; /* XOR the byte with the earlier checksum */ d->Msg.CheckSum[d->Msg.Count & 1] ^= rx_char; if (d->MsgRXState == RX_GetMessage) { d->Msg.Buffer[d->Msg.Count] = rx_char; d->Msg.Count++; /* This is not last byte in frame */ if (d->Msg.Count != d->Msg.Length+(d->Msg.Length%2)+2) return ERR_NONE; /* Checksum is incorrect */ if (d->Msg.CheckSum[0] != d->Msg.CheckSum[1]) { smprintf_level(s, D_ERROR, "[ERROR: checksum]\n"); free(d->Msg.Buffer); d->Msg.Buffer = NULL; d->Msg.Length = 0; d->MsgRXState = RX_Sync; return ERR_NONE; } seq_num = d->Msg.Buffer[d->Msg.Length-1]; if (d->Msg.Type == FBUS2_ACK_BYTE) { smprintf_level(s, D_TEXT, "[Received Ack of type %02x, seq %02x]\n", d->Msg.Buffer[0], seq_num); free(d->Msg.Buffer); d->Msg.Buffer = NULL; d->Msg.Length = 0; d->MsgRXState = RX_Sync; return ERR_NONE; } frm_num = d->Msg.Buffer[d->Msg.Length-2]; if ((seq_num & 0x40) == 0x40) { d->FramesToGo = frm_num; d->MultiMsg.Length = 0; d->MultiMsg.Type = d->Msg.Type; d->MultiMsg.Destination = d->Msg.Destination; d->MultiMsg.Source = d->Msg.Source; } if ((seq_num & 0x40) != 0x40 && d->FramesToGo != frm_num) { smprintf_level(s, D_ERROR, "[ERROR: Missed part of multiframe msg]\n"); free(d->Msg.Buffer); d->Msg.Buffer = NULL; d->Msg.Length = 0; d->MsgRXState = RX_Sync; return ERR_NONE; } if ((seq_num & 0x40) != 0x40 && d->Msg.Type != d->MultiMsg.Type) { smprintf_level(s, D_ERROR, "[ERROR: Multiframe msg in multiframe msg]\n"); free(d->Msg.Buffer); d->Msg.Buffer = NULL; d->Msg.Length = 0; d->MsgRXState = RX_Sync; return ERR_NONE; } if (d->MultiMsg.BufferUsed < d->MultiMsg.Length+d->Msg.Length-2) { d->MultiMsg.BufferUsed = d->MultiMsg.Length+d->Msg.Length-2; d->MultiMsg.Buffer = (unsigned char *)realloc(d->MultiMsg.Buffer,d->MultiMsg.BufferUsed); } memcpy(d->MultiMsg.Buffer+d->MultiMsg.Length,d->Msg.Buffer,d->Msg.Length-2); d->MultiMsg.Length = d->MultiMsg.Length+d->Msg.Length-2; free(d->Msg.Buffer); d->Msg.Buffer = NULL; d->Msg.Length = 0; d->FramesToGo--; /* do not ack debug trace, as this could generate a * (feedback loop) flood of which even Noah would be scared. */ if (d->Msg.Type != 0) { FBUS2_SendAck(s,d->Msg.Type,((unsigned char)(seq_num & 0x0f))); } if (d->FramesToGo == 0) { s->Phone.Data.RequestMsg = &d->MultiMsg; s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s); } d->MsgRXState = RX_Sync; return ERR_NONE; } if (d->MsgRXState == RX_GetLength2) { d->Msg.Length = d->Msg.Length + rx_char; d->Msg.Buffer = (unsigned char *)malloc(d->Msg.Length+3); d->MsgRXState = RX_GetMessage; return ERR_NONE; } if (d->MsgRXState == RX_GetLength1) { d->Msg.Length = rx_char * 256; d->MsgRXState = RX_GetLength2; return ERR_NONE; } if (d->MsgRXState == RX_GetType) { d->Msg.Type = rx_char; d->MsgRXState = RX_GetLength1; return ERR_NONE; } if (d->MsgRXState == RX_GetSource) { if (rx_char != FBUS2_DEVICE_PHONE) { smprintf_level(s, D_ERROR, "[ERROR: incorrect char - %02x, not %02x]\n", rx_char, FBUS2_DEVICE_PHONE); d->MsgRXState = RX_Sync; return ERR_NONE; } d->Msg.Source = rx_char; d->MsgRXState = RX_GetType; return ERR_NONE; } if (d->MsgRXState == RX_GetDestination) { if (rx_char != FBUS2_DEVICE_PC) { smprintf_level(s, D_ERROR, "[ERROR: incorrect char - %02x, not %02x]\n", rx_char, FBUS2_DEVICE_PC); d->MsgRXState = RX_Sync; return ERR_NONE; } d->Msg.Destination = rx_char; d->MsgRXState = RX_GetSource; return ERR_NONE; } if (d->MsgRXState == RX_Sync) { switch (s->ConnectionType) { case GCT_FBUS2: case GCT_FBUS2DLR3: case GCT_DKU5FBUS2: case GCT_FBUS2PL2303: case GCT_FBUS2BLUE: case GCT_BLUEFBUS2: if (rx_char == FBUS2_FRAME_ID) correct = TRUE; break; case GCT_FBUS2IRDA: if (rx_char == FBUS2_IRDA_FRAME_ID) correct = TRUE; break; default: break; } if (!correct) { smprintf_level(s, D_ERROR, "[ERROR: incorrect char - %02x, not %02x]\n", rx_char, (s->ConnectionType == GCT_FBUS2IRDA) ? FBUS2_IRDA_FRAME_ID : FBUS2_FRAME_ID); if (rx_char == 0x20) { smprintf(s, "0x20 reply detected...\n"); smprintf(s, "Trying to reinit connection...\n"); FBUS2_Initialise(s); } return ERR_NONE; } d->Msg.CheckSum[0] = rx_char; d->Msg.CheckSum[1] = 0; d->Msg.Count = 0; d->MsgRXState = RX_GetDestination; return ERR_NONE; } return ERR_NONE; }
static GSM_Error MBUS2_StateMachine(GSM_StateMachine *s, unsigned char rx_char) { GSM_Phone_Functions *Phone = s->Phone.Functions; GSM_Protocol_MBUS2Data *d = &s->Protocol.Data.MBUS2; d->Msg.CheckSum[0] = d->Msg.CheckSum[1]; d->Msg.CheckSum[1] ^= rx_char; if (d->MsgRXState == RX_GetMessage) { d->Msg.Buffer[d->Msg.Count] = rx_char; d->Msg.Count++; /* This is not last byte in frame */ if (d->Msg.Count != d->Msg.Length+2) return ERR_NONE; /* Checksum is incorrect */ if (d->Msg.CheckSum[0] != rx_char) { smprintf_level(s, D_ERROR, "[ERROR: checksum]\n"); d->MsgRXState = RX_Sync; return ERR_NONE; } if (d->Msg.Destination != MBUS2_DEVICE_PHONE) { MBUS2_SendAck(s, d->Msg.Type, d->Msg.Buffer[d->Msg.Count-2]); s->Phone.Data.RequestMsg = &d->Msg; s->Phone.Data.DispatchError = Phone->DispatchMessage(s); } d->MsgRXState = RX_Sync; return ERR_NONE; } if (d->MsgRXState == RX_GetLength2) { if (d->Msg.Type == MBUS2_ACK_BYTE) { smprintf_level(s, D_TEXT, "[Received Ack]\n"); d->MsgRXState = RX_Sync; return ERR_NONE; } d->Msg.Length = d->Msg.Length + rx_char; if (d->Msg.BufferUsed < d->Msg.Length+2) { d->Msg.BufferUsed = d->Msg.Length+2; d->Msg.Buffer = (unsigned char *)realloc(d->Msg.Buffer,d->Msg.BufferUsed); } d->MsgRXState = RX_GetMessage; return ERR_NONE; } if (d->MsgRXState == RX_GetLength1) { d->Msg.Length = rx_char * 256; d->MsgRXState = RX_GetLength2; return ERR_NONE; } if (d->MsgRXState == RX_GetType) { d->Msg.Type = rx_char; d->MsgRXState = RX_GetLength1; return ERR_NONE; } if (d->MsgRXState == RX_GetSource) { if (rx_char != MBUS2_DEVICE_PHONE && rx_char != MBUS2_DEVICE_PC) { smprintf_level(s, D_ERROR, "[ERROR: incorrect char - %02x, not %02x and %02x]\n", rx_char, MBUS2_DEVICE_PHONE, MBUS2_DEVICE_PC); d->MsgRXState = RX_Sync; return ERR_NONE; } d->Msg.Source = rx_char; d->MsgRXState = RX_GetType; return ERR_NONE; } if (d->MsgRXState == RX_GetDestination) { if (rx_char != MBUS2_DEVICE_PC && rx_char != MBUS2_DEVICE_PHONE) { smprintf_level(s, D_ERROR, "[ERROR: incorrect char - %02x, not %02x and %02x]\n", rx_char, MBUS2_DEVICE_PHONE, MBUS2_DEVICE_PC); d->MsgRXState = RX_Sync; return ERR_NONE; } d->Msg.Destination = rx_char; d->MsgRXState = RX_GetSource; return ERR_NONE; } if (d->MsgRXState == RX_Sync) { if (rx_char != MBUS2_FRAME_ID) { smprintf_level(s, D_ERROR, "[ERROR: incorrect char - %02x, not %02x]\n", rx_char, MBUS2_FRAME_ID); return ERR_NONE; } d->Msg.CheckSum[1] = MBUS2_FRAME_ID; d->Msg.Count = 0; d->MsgRXState = RX_GetDestination; return ERR_NONE; } return ERR_NONE; }
GSM_Error GSM_InitConnection_Log(GSM_StateMachine *s, int ReplyNum, GSM_Log_Function log_function, void *user_data) { GSM_Error error; GSM_DateTime current_time; int i; for (i=0;i<s->ConfigNum;i++) { s->CurrentConfig = &s->Config[i]; /* Skip non configured sections */ if (s->CurrentConfig->Connection == NULL) { smprintf_level(s, D_ERROR, "[Empty section - %d]\n", i); continue; } s->Speed = 0; s->ReplyNum = ReplyNum; s->Phone.Data.ModelInfo = GetModelData(s, "unknown", NULL, NULL); s->Phone.Data.Manufacturer[0] = 0; s->Phone.Data.Model[0] = 0; s->Phone.Data.Version[0] = 0; s->Phone.Data.VerDate[0] = 0; s->Phone.Data.VerNum = 0; s->Phone.Data.StartInfoCounter = 0; s->Phone.Data.SentMsg = NULL; s->Phone.Data.HardwareCache[0] = 0; s->Phone.Data.ProductCodeCache[0] = 0; s->Phone.Data.EnableIncomingCall = FALSE; s->Phone.Data.EnableIncomingSMS = FALSE; s->Phone.Data.EnableIncomingCB = FALSE; s->Phone.Data.EnableIncomingUSSD = FALSE; s->User.UserReplyFunctions = NULL; s->User.IncomingCall = NULL; s->User.IncomingSMS = NULL; s->User.IncomingCB = NULL; s->User.IncomingUSSD = NULL; s->User.SendSMSStatus = NULL; s->LockFile = NULL; s->opened = FALSE; s->Phone.Functions = NULL; s->di = GSM_none_debug; s->di.use_global = s->CurrentConfig->UseGlobalDebugFile; if (!s->di.use_global) { GSM_SetDebugFunction(log_function, user_data, &s->di); GSM_SetDebugLevel(s->CurrentConfig->DebugLevel, &s->di); error = GSM_SetDebugFile(s->CurrentConfig->DebugFile, &s->di); if (error != ERR_NONE) { GSM_LogError(s, "Init:GSM_SetDebugFile" , error); return error; } } smprintf_level(s, D_ERROR, "[Gammu - %s built %s %s using %s]\n", GAMMU_VERSION, __TIME__, __DATE__, GetCompiler() ); StripSpaces(s->CurrentConfig->Connection); StripSpaces(s->CurrentConfig->Model); StripSpaces(s->CurrentConfig->Device); smprintf_level(s, D_ERROR, "[Connection - \"%s\"]\n", s->CurrentConfig->Connection); smprintf_level(s, D_ERROR, "[Connection index - %d]\n", i); smprintf_level(s, D_ERROR, "[Model type - \"%s\"]\n", s->CurrentConfig->Model); smprintf_level(s, D_ERROR, "[Device - \"%s\"]\n", s->CurrentConfig->Device); if (strlen(GetOS()) != 0) { smprintf_level(s, D_ERROR, "[Running on - %s]\n", GetOS()); } if (GSM_GetDI(s)->dl == DL_BINARY) { smprintf(s,"%c",((unsigned char)strlen(GAMMU_VERSION))); smprintf(s,"%s",GAMMU_VERSION); } error = GSM_RegisterAllConnections(s, s->CurrentConfig->Connection); if (error != ERR_NONE) { GSM_LogError(s, "Init:GSM_RegisterAllConnections" , error); return error; } autodetect: /* Model auto */ /* Try to guess correct driver based on model */ if (s->CurrentConfig->Model[0] == 0 && s->ConnectionType != GCT_NONE && s->ConnectionType != GCT_IRDAOBEX && s->ConnectionType != GCT_BLUEOBEX && s->ConnectionType != GCT_BLUEGNAPBUS && s->ConnectionType != GCT_IRDAGNAPBUS && s->ConnectionType != GCT_BLUES60) { error = GSM_TryGetModel(s); /* Fall back to other configuraitons if the device is not existing (or similar error) */ if ((i != s->ConfigNum - 1) && ( (error == ERR_DEVICEOPENERROR) || (error == ERR_DEVICELOCKED) || (error == ERR_DEVICENOTEXIST) || (error == ERR_DEVICEBUSY) || (error == ERR_DEVICENOPERMISSION) || (error == ERR_DEVICENODRIVER) || (error == ERR_DEVICENOTWORK))) { GSM_CloseConnection(s); continue; } if (error != ERR_NONE) { GSM_LogError(s, "Init:GSM_TryGetModel" , error); return error; } } /* Switching to "correct" module */ error = GSM_RegisterAllPhoneModules(s); /* If user selected soemthing which is not supported, try autodetection */ if (s->CurrentConfig->Model[0] != 0 && error == ERR_UNKNOWNMODELSTRING) { smprintf(s, "Configured model %s is not known, retrying with autodetection!\n", s->CurrentConfig->Model); s->CurrentConfig->Model[0] = 0; goto autodetect; } if (error != ERR_NONE) { GSM_LogError(s, "Init:GSM_RegisterAllPhoneModules" , error); return error; } /* We didn't open device earlier ? Make it now */ if (!s->opened) { error = GSM_OpenConnection(s); if ((i != s->ConfigNum - 1) && ( (error == ERR_DEVICEOPENERROR) || (error == ERR_DEVICELOCKED) || (error == ERR_DEVICENOTEXIST) || (error == ERR_DEVICEBUSY) || (error == ERR_DEVICENOPERMISSION) || (error == ERR_DEVICENODRIVER) || (error == ERR_DEVICENOTWORK))) { GSM_CloseConnection(s); continue; } if (error != ERR_NONE) { GSM_LogError(s, "Init:GSM_OpenConnection" , error); return error; } } /* Initialize phone layer */ error=s->Phone.Functions->Initialise(s); if (error == ERR_TIMEOUT && i != s->ConfigNum - 1) { GSM_CloseConnection(s); continue; } if (error != ERR_NONE) { GSM_LogError(s, "Init:Phone->Initialise" , error); return error; } if (s->CurrentConfig->StartInfo) { s->Phone.Functions->ShowStartInfo(s,TRUE); s->Phone.Data.StartInfoCounter = 30; } if (s->CurrentConfig->SyncTime) { GSM_GetCurrentDateTime (¤t_time); s->Phone.Functions->SetDateTime(s,¤t_time); } /* For debug it's good to have firmware and real model version and manufacturer */ error=s->Phone.Functions->GetManufacturer(s); if (error == ERR_TIMEOUT && i != s->ConfigNum - 1) { GSM_CloseConnection(s); continue; } if (error != ERR_NONE && error != ERR_NOTSUPPORTED) { GSM_LogError(s, "Init:Phone->GetManufacturer" , error); return error; } error=s->Phone.Functions->GetModel(s); if (error != ERR_NONE && error != ERR_NOTSUPPORTED) { GSM_LogError(s, "Init:Phone->GetModel" , error); return error; } error=s->Phone.Functions->GetFirmware(s); if (error != ERR_NONE && error != ERR_NOTSUPPORTED) { GSM_LogError(s, "Init:Phone->GetFirmware" , error); return error; } smprintf(s,"[Connected]\n"); return ERR_NONE; } return ERR_UNCONFIGURED; }
GSM_Error GSM_DispatchMessage(GSM_StateMachine *s) { GSM_Error error = ERR_UNKNOWNFRAME; GSM_Protocol_Message *msg = s->Phone.Data.RequestMsg; GSM_Phone_Data *Phone = &s->Phone.Data; gboolean disp = FALSE; GSM_Reply_Function *Reply; int reply; GSM_DumpMessageLevel2Recv(s, msg->Buffer, msg->Length, msg->Type); GSM_DumpMessageLevel3Recv(s, msg->Buffer, msg->Length, msg->Type); Reply = s->User.UserReplyFunctions; if (Reply != NULL) { error = CheckReplyFunctions(s,Reply,&reply); } if (error == ERR_UNKNOWNFRAME) { Reply = s->Phone.Functions->ReplyFunctions; error = CheckReplyFunctions(s,Reply,&reply); } if (error==ERR_NONE) { error=Reply[reply].Function(msg, s); if (Reply[reply].requestID==Phone->RequestID) { if (error == ERR_NEEDANOTHERANSWER) { error = ERR_NONE; } else { Phone->RequestID=ID_None; } } } if (strcmp(s->Phone.Functions->models,"NAUTO")) { disp = TRUE; switch (error) { case ERR_UNKNOWNRESPONSE: smprintf_level(s, D_ERROR, "\nUNKNOWN response"); break; case ERR_UNKNOWNFRAME: smprintf_level(s, D_ERROR, "\nUNKNOWN frame"); break; case ERR_FRAMENOTREQUESTED: smprintf_level(s, D_ERROR, "\nFrame not request now"); break; default: disp = FALSE; } if (error == ERR_UNKNOWNFRAME || error == ERR_FRAMENOTREQUESTED) { error = ERR_TIMEOUT; } } if (disp) { smprintf(s,". Please report the error, see <http://wammu.eu/support/bugs/>. Thank you\n"); if (Phone->SentMsg != NULL) { smprintf(s,"LAST SENT frame "); smprintf(s, "type 0x%02X/length %ld", Phone->SentMsg->Type, (long)Phone->SentMsg->Length); DumpMessage(GSM_GetDI(s), Phone->SentMsg->Buffer, Phone->SentMsg->Length); } smprintf(s, "RECEIVED frame "); smprintf(s, "type 0x%02X/length 0x%lx/%ld", msg->Type, (long)msg->Length, (long)msg->Length); DumpMessage(GSM_GetDI(s), msg->Buffer, msg->Length); smprintf(s, "\n"); } return error; }